package com.ia.aistream.service.dxfcomponent.impl;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import com.github.pagehelper.PageHelper;
import com.ia.aistream.common.core.page.PageDomain;
import com.ia.aistream.common.core.page.TableSupport;
import com.ia.aistream.common.utils.DateUtils;
import com.ia.aistream.common.utils.StringUtils;
import com.ia.aistream.common.utils.sql.SqlUtil;
import com.ia.aistream.manager.common.ICommonFileManager;
import com.ia.aistream.manager.dxfcomponent.conf.DrawConf;
import com.ia.aistream.manager.dxfcomponent.util.DrawExtensionUtil;
import com.ia.aistream.manager.dxfcomponent.util.FileUtilTest;
import com.ia.aistream.mapper.dxfcomponent.DxfDrawMapper;
import com.ia.aistream.model.common.entity.CommonFile;
import com.ia.aistream.model.dxfcomponent.entity.DrawDxfComp;
import com.ia.aistream.model.dxfcomponent.entity.DxfDraw;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ia.aistream.mapper.dxfcomponent.DxfComponentMapper;
import com.ia.aistream.model.dxfcomponent.entity.DxfComponent;
import com.ia.aistream.service.dxfcomponent.IDxfComponentService;
import com.ia.aistream.common.core.text.Convert;
import org.springframework.web.client.RestTemplate;


/**
 * dxf文件部件Service业务层处理
 * 
 * @author ymj
 * @date 2020-12-04
 */
@Service
public class DxfComponentServiceImpl implements IDxfComponentService 
{
    @Autowired
    private DxfComponentMapper dxfComponentMapper;
    @Autowired
    private DxfDrawMapper dxfDrawMapper;
    @Autowired
    private ICommonFileManager commonFileManager;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DrawConf drawConf;

//    /** 注入配置的dxf文件的地址 */
//    @Value("${drawConfiguration.dxfPath}")
//    private String dxfPath;

//    /** 注入文件所在的路径 */
//    @Value("${drawConfiguration.fileDir}")
//    private String fileDir;
    /**
     * 查询dxf文件部件
     * 
     * @param componentId dxf文件部件ID
     * @return dxf文件部件
     */
    @Override
    public DxfComponent selectDxfComponentById(Long componentId)
    {
        return dxfComponentMapper.selectDxfComponentById(componentId);
    }

    @Override
    public List<DrawDxfComp> selectDrawDxfCompList(DrawDxfComp drawDxfComp) {
        List<DrawDxfComp> componentList = dxfComponentMapper.selectDrawDxfCompList(drawDxfComp);

        return componentList;
    }

    /**
     * 展示设备信息
     * @param dxfComponent dxf文件部件
     * @return dxf文件部件
     */
    @Override
    public List<DxfComponent> selectDxfComponentList(DxfComponent dxfComponent)
    {
        List<DxfComponent> componentList = dxfComponentMapper.selectDxfComponentList(dxfComponent);

        return DrawExtensionUtil.sortEquipment(componentList);
    }

    protected void startPage()
    {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
        {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    /**
     * 新增dxf文件部件
     * 
     * @param dxfComponent dxf文件部件
     * @return 结果
     */
    @Override
    public int insertDxfComponent(DxfComponent dxfComponent)
    {
        dxfComponent.setCreateTime(DateUtils.getNowDate());
        return dxfComponentMapper.insertDxfComponent(dxfComponent);
    }

    /**
     * 修改dxf文件部件
     * 
     * @param dxfComponent dxf文件部件
     * @return 结果
     */
    @Override
    public int updateDxfComponent(DxfComponent dxfComponent)
    {
        dxfComponent.setUpdateTime(DateUtils.getNowDate());
        return dxfComponentMapper.updateDxfComponent(dxfComponent);
    }

    /**
     * 删除dxf文件部件对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteDxfComponentByIds(String ids)
    {
        return dxfComponentMapper.deleteDxfComponentByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除dxf文件部件信息
     * 
     * @param componentId dxf文件部件ID
     * @return 结果
     */
    @Override
    public int deleteDxfComponentById(Long componentId)
    {
        return dxfComponentMapper.deleteDxfComponentById(componentId);
    }

    /***
     * 1、找到dxf文件所在的位置
     * 2、将dxf文件的文件内容修改
     * 2、将dxf文件转化为PDF
     * 圈定设备并返回转化的文件的地址
     * @param componentId
     * @return
     */
    @Override
    public String drawCircleService(Long componentId) throws Exception {
        // 获取设备对象
        DxfComponent dxfComponent = dxfComponentMapper.selectDxfComponentById(componentId);

        // 获取索引信息对象
        DxfDraw dxfDraw = dxfDrawMapper.selectDxfDrawById(dxfComponent.getDrawId());
        // 获取文件对象
        CommonFile commonFile = commonFileManager.selectCommonFileById(dxfDraw.getFileId());

        // 获取文件后缀
        String fileExt = commonFile.getFileExt();
        String fileType = "/" + fileExt;
        // 获取dxf文件在本地的路径
        String fileName = drawConf.getFileDir() + commonFile.getDownloadUrl().substring(commonFile.getDownloadUrl().indexOf(fileType),
                commonFile.getDownloadUrl().lastIndexOf("."+fileExt));
        fileName = fileName.substring(0, fileName.lastIndexOf("/")+1) + fileName.substring(fileName.lastIndexOf("_")+1);
        // 拼接生成的dxf文件所在的路径
        String newFilePath = fileName + "_" + dxfComponent.getContentC() + ".dxf";

        fileName = fileName + ".dxf";

        // 获取图纸的大小
        List<String> list = FileUtilTest.readDxfDataSource(fileName);
        double[] size = FileUtilTest.drawSize(list);

        // 画圆
        writeDrawCircle(dxfComponent, fileName, newFilePath, size);

        String imgName = dxfToImg(newFilePath);

        imgName = "/profile" + imgName.substring(imgName.indexOf(fileType));

        return imgName;
    }

    /****
     * 调用接口，实现dxf文件的转为图片
     * @param srcFile
     * @return private String dxfToImg(String srcFile, Long x, Long y){
     */
    private String dxfToImg(String srcFile) throws Exception{

        String imgName = "";

        String cmd = drawConf.getAcmeCADConverter()
                + " /r /e /ls /p 3 /f 6 /w 295mm /h 200mm /res 400 /a 0 /lw 1 "
                + srcFile; // filePath即旧图片路径，比如D:/testPic.dwg
        Runtime rt = Runtime.getRuntime();
        Process p = rt.exec(cmd);
        p.waitFor();// 等待 进程执行结束
        imgName = srcFile.replace(".dxf", ".png");

         return imgName;
    }
    /**
     * 将圈定信息写入文件
     * @param filePath
     * @param newFilePath
     */
    private void writeDrawCircle(DxfComponent dxfComponent, String filePath, String newFilePath, double[] size){

        // 获取上传文件的大小
        double lx = size[0];
        double rx = size[2];
//        double xmode = size[6];
        double width = Math.abs(lx - rx);
        double px = dxfComponent.getPositionX();
        double py = dxfComponent.getPositionY();
        double cr = 0.0;
        cr = 12.0/1000 * width;
//        if(width<7000.0){
////            px =  (dxfComponent.getPositionX()+ 30/xmode );
//           // py = (dxfComponent.getPositionY()- 10/xmode);
//            cr = 60/xmode;
//        }else if(width>20000.0){
//            //px = (dxfComponent.getPositionX()+ 225 * xmode );
//           // py = (dxfComponent.getPositionY()- 30 * xmode);
//            cr = 160 * xmode;
//        }else{
////            px = dxfComponent.getPositionX()+ 225;
////            py = dxfComponent.getPositionY()- 30;
//            cr = 160;
//        }
        // 拼接画圆的信息 33C11
//        String circleStr = "  0\n" +
//                "CIRCLE\n" +
//                "  5\n" +
//                "42E70\n" +
//                "330\n" +
//                "1F\n" +
//                "100\n" +
//                "AcDbEntity\n" +
//                "  8\n" +
//                dxfComponent.getLayer() +
//                "\n" +
//                " 62\n" +
//                "     240\n" +
//                "370\n" +
//                "    30\n" + // 表示线条粗细
//                "100\n" +
//                "AcDbCircle\n" +
//                " 10\n" +
//                px +
//                "\n" +
//                " 20\n" +
//                py +
//                "\n" +
//                " 30\n" +
//                "0.0\n" +
//                " 40\n" +
//                cr +"\n";

        String circleStr = "  0\n" +
                "CIRCLE\n" +
                "  5\n" +
                "42E70\n" +
                "330\n" +
                "1F\n" +
                "100\n" +
                "AcDbEntity\n" +
                "  8\n" +
                dxfComponent.getLayer() +
                "\n" +
                " 62\n" +
                "     1\n" +
                "370\n" +
                "    60\n" +
                "100\n" +
                "AcDbCircle\n" +
                " 10\n" +
                px +
                "\n" +
                " 20\n" +
                + py +
                "\n" +
                " 30\n" +
                "0.0\n" +
                " 40\n" +
                cr +
                "\n";
        // 获取文件的原始数据
        List<String> strings = FileUtilTest.readDxfDataSource(filePath);
        // 需要写入文件的位置
        List<String> list = new ArrayList<>();
        // 记录需要写入的点
        int x = -2;
        boolean flag = false;
        boolean sure = false;
        boolean start = false;
        String strX = String.valueOf(dxfComponent.getPositionX());
        String strY = String.valueOf(dxfComponent.getPositionY());
        for(int i=0; i< strings.size(); i++){
            // 记录原始数据
            list.add(strings.get(i) + "\n");
            if("ENTITIES".equals(strings.get(i))){
                start = true;
            }else if(start && strings.get(i).startsWith(strX)) {
                flag = true;
            }else if(flag && strings.get(i).startsWith(strY)) {
                sure = true;
                flag = false;
                start = false;
            }else if(sure && "  0".equals(strings.get(i)) && "ENDSEC".equals(strings.get(i+1)) && "  0".equals(strings.get(i+2)) && "SECTION".equals(strings.get(i+3))){
                list.add(i, circleStr);
                sure = false;
            }
        }

        writeNIO(list, newFilePath);
    }

    /***
     * 将数据写入到本地文件
     * @param list
     * @param newFilePath
     */
    private void writeNIO(List<String> list, String newFilePath) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(newFilePath);
            FileChannel channel = fos.getChannel();
            byte[] by = null;
            String[] strings = list.toArray(new String[list.size()]);
            for(String s:strings){
                ByteBuffer src = Charset.forName("utf8").encode(s);

                channel.write(src);
            }

        } catch (Exception ee) {
            ee.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
